package com.jinglvhuanjing.app.helper.statusbar;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.jinglvhuanjing.app.utils.ScreenUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;


@TargetApi(Build.VERSION_CODES.M)
public class StatusBarHelper {

    private final String TAG = "StatusBarHelper";
    private static String mNavBarOverride;
    private final SystemBarConfig mSystemBarConfig;

    public StatusBarHelper(@NonNull Activity activity) {
        this.mSystemBarConfig = new SystemBarConfig(activity);
    }

    /**
     * 当前系统版本是否支持沉浸状态栏（系统版本在23以下使用沉浸式状态栏会有问题，所以建议在23及以上版本使用）
     *
     * @return 返回true则表示支持沉浸状态栏
     */
    public static boolean canImmerseStatusBar() {
        return ScreenUtils.isSupportImmerseStatusBar();
    }

    /**
     * 设置将内容沉浸到状态栏和导航栏中，即设置Activity全屏并且透明
     *
     * @param mActivity Activity
     */
    public void setScreenFullStatusBar(@NonNull Activity mActivity) {
        if (ScreenUtils.isSupportImmerseStatusBar()) {
            Window window = mActivity.getWindow();
            if (null != window) {
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(Color.TRANSPARENT);
            }
        }
    }

    /**
     * 设置将内容沉浸到导航栏中，实现真正的全屏
     *
     * @param mActivity Activity
     */
    public void setScreenFullNavigationBar(@NonNull Activity mActivity) {
        if (ScreenUtils.isSupportImmerseStatusBar()) {
            Window window = mActivity.getWindow();
            if (null != window) {
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(Color.TRANSPARENT);
                window.setNavigationBarColor(Color.TRANSPARENT);
            }
        }
    }

    /**
     * 获取系统状态栏和导航栏的配置信息
     *
     * @return {@link SystemBarConfig}
     */
    @NonNull
    public SystemBarConfig getSystemBarConfig() {
        return mSystemBarConfig;
    }

    /**
     * 修改状态栏颜色，仅支持6.0及以上的系统版本
     *
     * @param colorId 颜色id
     */
    public void setStatusBarColor(@NonNull Activity mActivity, @ColorInt int colorId) {
        Window window = mActivity.getWindow();
        if (window != null && ScreenUtils.isSupportImmerseStatusBar()) {
            window.setStatusBarColor(colorId);
        }
    }

    /**
     * 修改状态栏颜色，仅支持6.0及以上的系统版本
     *
     * @param colorId 颜色资源
     */
    public void setStatusBarColorRes(@NonNull Activity mActivity, @ColorRes int colorId) {
       setStatusBarColor(mActivity, ContextCompat.getColor(mActivity, colorId));
    }

    /**
     * 修改导航栏颜色，仅支持6.0及以上的系统版本
     *
     * @param colorId 颜色资源
     */
    public void setNavigationBarColor(@NonNull Activity mActivity, @ColorInt int colorId) {
        Window window = mActivity.getWindow();
        if (window != null && ScreenUtils.isSupportImmerseStatusBar()) {
            window.setNavigationBarColor(colorId);
        }
    }

    /**
     * 设置状态栏主题色
     *
     * @param mActivity Activity
     * @param isDark    是否深色主题
     */
    public void setStatusBarThemeDark(@NonNull Activity mActivity, boolean isDark) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            this.setThemeCommonui(mActivity, isDark);
        } else if (OSHelper.isMiui()) {
            this.setThemeMiui(mActivity, isDark);
        } else if (OSHelper.isFlyme()) {
            this.setThemeFlymeui(mActivity, isDark);
        }
    }

    /**
     * 设置6.0 状态栏深色浅色切换
     *
     * @param activity Activity
     * @param dark     是否深色主题
     */
    private void setThemeCommonui(@NonNull Activity activity, boolean dark) {
        Log.d(TAG, "[6.0通用]切换状态栏内容主题色深浅！");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            View decorView = activity.getWindow().getDecorView();
            int vis = decorView.getSystemUiVisibility();
            if (dark) {
                vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            } else {
                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
            if (decorView.getSystemUiVisibility() != vis) {
                decorView.setSystemUiVisibility(vis);
            }
        }
    }

    /**
     * 设置 Flyme 状态栏深色浅色切换
     *
     * @param activity Activity
     * @param dark     是否深色主题
     */
    private void setThemeFlymeui(@NonNull Activity activity, boolean dark) {
        Log.d(TAG, "切换[魅族]的状态栏内容主题！");
        try {
            Window window = activity.getWindow();
            WindowManager.LayoutParams lp = window.getAttributes();
            Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
            Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
            darkFlag.setAccessible(true);
            meizuFlags.setAccessible(true);
            int bit = darkFlag.getInt(null);
            int value = meizuFlags.getInt(lp);
            if (dark) {
                value |= bit;
            } else {
                value &= ~bit;
            }
            meizuFlags.setInt(lp, value);
            window.setAttributes(lp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置 Miui 状态栏深色浅色切换
     *
     * @param activity Activity
     * @param dark     是否深色主题
     */
    private void setThemeMiui(@NonNull Activity activity, boolean dark) {
        Log.d(TAG, "切换[小米]的状态栏内容主题！");
        try {
            Window window = activity.getWindow();
            Class<?> clazz = activity.getWindow().getClass();
            @SuppressLint("PrivateApi") Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
            Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
            int darkModeFlag = field.getInt(layoutParams);
            Method extraFlagField = clazz.getDeclaredMethod("setExtraFlags", int.class, int.class);
            extraFlagField.setAccessible(true);
            if (dark) {
                extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
            } else {
                extraFlagField.invoke(window, 0, darkModeFlag);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void onDestroy() {
    }

    // -------------------------------------- 系统配置静态类  -------------------------------------

    static {
        try {
            // Android允许系统属性覆盖导航栏的存在。
            Class aClass = Class.forName("android.os.SystemProperties");
            Method method = aClass.getDeclaredMethod("get", String.class);
            method.setAccessible(true);
            mNavBarOverride = (String) method.invoke(null, "qemu.hw.mainkeys");
        } catch (Throwable e) {
            mNavBarOverride = null;
        }
    }

    public static class SystemBarConfig {

        private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
        private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
        private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
        private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
        private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";

        /*** 状态栏高度 ***/
        private final int mStatusBarHeight;
        /*** 菜单栏高度 ***/
        private final int mActionBarHeight;
        /*** 是否有导航栏 ***/
        private final boolean mHasNavigationBar;
        /*** 导航栏高度 ***/
        private final int mNavigationBarHeight;
        /*** 导航栏宽度 ***/
        private final int mNavigationBarWidth;
        /*** 屏幕是否是竖屏 ***/
        private final boolean mInPortrait;
        /*** 宽和高的最小值 ***/
        private final float mSmallestWidthDp;

        /**
         * 在当前设备上，导航栏是否在屏幕底部？
         * 在某些设备上，导航栏可能出现在屏幕的右侧。
         *
         * @return 如果导航显示在屏幕底部，则为true，否则为false
         */
        public boolean isNavigationAtBottom() {
            return (mSmallestWidthDp >= 600 || mInPortrait);
        }

        /**
         * 获取系统状态栏高度
         *
         * @return 系统状态栏高度（px）
         */
        public int getStatusBarHeight() {
            return mStatusBarHeight;
        }

        /**
         * 获取系统ActionBar的高度，这个值仅具有参考价值，因为很多开发者喜欢把ActionBar的高度固定。
         * 例如：我就喜欢把ActionBar固定50DP
         *
         * @return ActionBar的高度（px）
         */
        public int getActionBarHeight() {
            return mActionBarHeight;
        }

        /**
         * 当前设备是否有导航栏
         *
         * @return 如果此设备使用软键导航，则为true，否则为false。
         */
        public boolean hasNavigtionBar() {
            return mHasNavigationBar;
        }

        /**
         * 获取导航栏高度，如果没有导航栏则等于0
         *
         * @return 导航栏高度（px）
         */
        public int getNavigationBarHeight() {
            return mNavigationBarHeight;
        }

        /**
         * 获取垂直放置在屏幕上时系统导航栏的宽度，如果没有导航栏，则等于0
         *
         * @return 导航栏的宽度（px）
         */
        public int getNavigationBarWidth() {
            return mNavigationBarWidth;
        }

        private SystemBarConfig(@NonNull Activity activity) {
            final Resources resources = activity.getResources();
            this.mInPortrait = (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
            this.mSmallestWidthDp = getSmallestWidthDp(activity);
            this.mStatusBarHeight = getInternalDimensionSize(resources, STATUS_BAR_HEIGHT_RES_NAME);
            this.mActionBarHeight = getActionBarHeight(activity, resources);
            this.mNavigationBarHeight = getNavigationBarHeight(activity, resources);
            this.mNavigationBarWidth = getNavigationBarWidth(activity, resources);
            this.mHasNavigationBar = (mNavigationBarHeight > 0);
        }

        /**
         * 获取ActionBar的高度，但我们的应用高度一般取值是固定值50DP，建议采用系统ActionBar高度
         */
        private int getActionBarHeight(@NonNull Activity activity, @NonNull Resources resources) {
            TypedValue typedValue = new TypedValue();
            activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true);
            return TypedValue.complexToDimensionPixelSize(typedValue.data, resources.getDisplayMetrics());
        }

        /**
         * 获取导航栏的高度，如果没有导航栏则高度等于0
         */
        private int getNavigationBarHeight(@NonNull Activity activity, @NonNull Resources resources) {
            if (this.hasNavigationBar(activity, resources)) {
                if (mInPortrait) {
                    return getInternalDimensionSize(resources, NAV_BAR_HEIGHT_RES_NAME);
                } else {
                    return getInternalDimensionSize(resources, NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME);
                }
            }
            return 0;
        }

        /**
         * 获取导航栏宽，如果没有导航栏则宽度等于0
         */
        private int getNavigationBarWidth(@NonNull Activity activity, @NonNull Resources resources) {
            if (this.hasNavigationBar(activity, resources)) {
                return getInternalDimensionSize(resources, NAV_BAR_WIDTH_RES_NAME);
            }
            return 0;
        }

        /**
         * 是否存在导航栏
         */
        private boolean hasNavigationBar(@NonNull Activity activity, @NonNull Resources resources) {
            int resourceId = resources.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
            if (resourceId != 0) {
                boolean hasNavigation = resources.getBoolean(resourceId);
                if ("1".equals(mNavBarOverride)) {
                    hasNavigation = false;
                } else if ("0".equals(mNavBarOverride)) {
                    hasNavigation = true;
                }
                return hasNavigation;
            } else {
                return !ViewConfiguration.get(activity).hasPermanentMenuKey();
            }
        }

        private int getInternalDimensionSize(@NonNull Resources resources, String key) {
            int result = 0;
            int resourceId = resources.getIdentifier(key, "dimen", "android");
            if (resourceId > 0) {
                result = resources.getDimensionPixelSize(resourceId);
            }
            return result;
        }

        private float getSmallestWidthDp(@NonNull Activity activity) {
            DisplayMetrics metrics = new DisplayMetrics();
            activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
            float widthDp = metrics.widthPixels / metrics.density;
            float heightDp = metrics.heightPixels / metrics.density;
            return Math.min(widthDp, heightDp);
        }
    }
}